<template>
  <div class="validate-input-container pb-3">
    <input
      v-if="tag !== 'textarea'"
      type="text"
      class="form-control"
      :class="{ 'is-invalid': inputRef.error }"
      :value="inputRef.val"
      @input="updateVaue"
      @blur="ValidateInpt"
      v-bind="$attrs"
    />
    <textarea
      class="form-control"
      cols="30"
      rows="10"
      v-else
      :value="inputRef.val"
      @input="updateVaue"
      @blur="ValidateInpt"
      :class="{ 'is-invalid': inputRef.error }"
      v-bind="$attrs"
    ></textarea>
    <span class="invalid-feedback" v-if="inputRef.error">{{
      inputRef.message
    }}</span>
  </div>
</template>

<script lang="ts">
import { defineComponent, reactive, PropType, onMounted, watch } from "vue";
import { emitter } from "./validateForm.vue";
const emailReg =
  /^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/; //邮箱正则

interface RuleProp {
  type: "required" | "email" | "custom"; // 必填| 必选, 它可以同时实现2种
  message: string;
  validator?: () => boolean;
}
export type RulesProp = RuleProp[];
export type TagType = "input" | "textarea";
export default defineComponent({
  props: {
    rules: Array as PropType<RulesProp>,
    modelValue: String,
    tag: {
      type: String as PropType<TagType>,
    },
  },
  setup(props, context) {
    // console.log(context.attrs);
    const inputRef = reactive({
      //如果一开始有值应该在你的modelValue 取值
      val: props.modelValue || "", //内容,他应该有2种情况
      error: false, // 返回一个错误，就是给他一个错误信息
      message: "", //返回的错误信息
    });
    // 你往里面输入内容鼠标只是起到了一个失焦和huojiao
    //你输入的内容是键盘事件
    const updateVaue = (e: KeyboardEvent) => {
      //HTMLInputElement是input标签这个元素
      //就是拿到你的数据源推断它是不是当前的元素，然后取到value值赋值给targetValue
      const targetValue = (e.target as HTMLInputElement).value;
      inputRef.val = targetValue;
      context.emit("value", targetValue);
    };
    watch(
      () => props.modelValue,
      (newValue) => {
        inputRef.val = newValue || "";
      }
    );
    const ValidateInpt = () => {
      // console.log(inputRef.val);
      if (props.rules) {
        const allPassed = props.rules.every((rule) => {
          let passed = true;
          inputRef.message = rule.message;
          switch (rule.type) {
            case "required":
              passed = inputRef.val.trim() !== "";
              break;
            case "email":
              passed = emailReg.test(inputRef.val);
              break;
            case "custom":
              passed = rule.validator ? rule.validator() : true;
              break;
            default:
              break;
          }
          return passed;
        });
        inputRef.error = !allPassed;
        return allPassed;
      }
      // return inputRef.error
    };
    onMounted(() => {
      //去执行你绑定的事件
      emitter.emit("form-item-created", ValidateInpt);
    });
    return {
      inputRef,
      ValidateInpt,
      updateVaue,
    };
  },
});
</script>

<style scoped></style>
